using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using Weight.Base;

namespace JHVideo
{
    class DHVideo : IVideo
    {
        /// <summary>
        /// 初始化状态
        /// </summary>
        private bool m_bInitSDK = false;

        /// <summary>
        /// 登录状态
        /// </summary>
        private IntPtr m_lUserID = IntPtr.Zero;

        /// <summary>
        /// 每个通道的句柄
        /// </summary>
        private List<IntPtr> mHandle = new List<IntPtr>();

        /// <summary>
        /// 默认摄像头的数量
        /// </summary>
        public int mCount = 2;

        private static fDisConnectCallBack m_DisConnectCallBack;
        private static fHaveReConnectCallBack m_ReConnectCallBack;
        private static fRealDataCallBackEx2 m_RealDataCallBackEx2;
        private static fSnapRevCallBack m_SnapRevCallBack;
        private NET_DEVICEINFO_Ex m_DeviceInfo;

        /// <summary>
        /// 初始化
        /// </summary>
        /// <returns></returns>
        public ResultEntity Init()
        {
            var result = ResultEntity.Default();
            m_DisConnectCallBack = new fDisConnectCallBack(DisConnectCallBack);
            m_ReConnectCallBack = new fHaveReConnectCallBack(ReConnectCallBack);
            m_RealDataCallBackEx2 = new fRealDataCallBackEx2(RealDataCallBackEx);
            m_SnapRevCallBack = new fSnapRevCallBack(SnapRevCallBack);
            try
            {
                NETClient.Init(m_DisConnectCallBack, IntPtr.Zero, null);
                NETClient.SetAutoReconnect(m_ReConnectCallBack, IntPtr.Zero);
                NETClient.SetSnapRevCallBack(m_SnapRevCallBack, IntPtr.Zero);
                m_bInitSDK = true;
                result = ResultEntity.Success("大华监控初始化成功!");
            }
            catch (Exception ex)
            {
                result = ResultEntity.Error("大华监控初始化异常:"+ex.Message+ex.StackTrace);
            }
            return result;
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public ResultEntity Login(LoginEntity model)
        {
            var res = ResultEntity.Default();
            try
            {
                if (!m_bInitSDK)
                {
                    res = ResultEntity.Error("大华登录失败，SDK 初始化失败!");
                    return res;
                }
                if (m_lUserID != IntPtr.Zero)
                {
                    bool result = NETClient.Logout(m_lUserID);
                    if (!result)
                    {
                        res = ResultEntity.Error("大华登录失败，退出上次登录失败，错误代码:"+NETClient.GetLastError());
                        return res;
                    }
                    m_lUserID = IntPtr.Zero;
                }

                m_DeviceInfo = new NET_DEVICEINFO_Ex();
                m_lUserID = NETClient.Login(model.IP,  Convert.ToUInt16(model.Port), model.Account, model.Pwd, EM_LOGIN_SPAC_CAP_TYPE.TCP, IntPtr.Zero, ref m_DeviceInfo);
                if (IntPtr.Zero == m_lUserID)
                {
                    res = ResultEntity.Error("大华登录失败，错误代码:" + NETClient.GetLastError());
                }
            }
            catch (Exception ex)
            {
                res = ResultEntity.Error("大华监控登录失败:"+ex.Message+ex.StackTrace);
            }
            return res;
        }

        /// <summary>
        /// 退出登录
        /// </summary>
        /// <returns></returns>
        private ResultEntity logOut()
        {
            var res = ResultEntity.Default();
            try
            {
                if (m_lUserID != IntPtr.Zero)
                {
                    bool result = NETClient.Logout(m_lUserID);
                    if (!result)
                    {
                        res = ResultEntity.Error("大华登录失败，退出上次登录失败，错误代码:" + NETClient.GetLastError());
                        return res;
                    }
                    else
                    {
                        res = ResultEntity.Success("大华设备退出登录成功!");
                        m_lUserID = IntPtr.Zero;
                    }
                }
            }
            catch (Exception ex)
            {
                res = ResultEntity.Error("大华退出登录异常:"+ex.Message+ex.StackTrace);
            }

            return res;
        }

        /// <summary>
        /// 实时预览数据
        /// </summary>
        /// <param name="Channels"></param>
        /// <returns></returns>
        public ResultEntity Play(List<ChannelEntity> Channels)
        {
            var rs = ResultEntity.Default();
            try
            {
                if (m_lUserID == IntPtr.Zero)
                {
                    rs = ResultEntity.Error("大华硬盘录像机登录失败，预览失败");
                    return rs;
                }
                if (Channels == null || Channels.Count == 0)
                {
                    rs = ResultEntity.Error("大华硬盘录像机无通道参数，预览失败");
                    return rs;
                }

                StopPlay(); //停止当前预览的通道

                ///开始预览
                StringBuilder msgBuider = new StringBuilder();
                ChannelEntity item;
                mHandle.Clear();
                for (int index = 0; index < Channels.Count; index++)
                {
                    mHandle.Add(IntPtr.Zero);
                    item = Channels[index];
                    if (item == null || item.Handle == null || item.ChannelNo < 0)
                    {
                        if (item != null) msgBuider.Append("大华设备通道号:" + item.ChannelNo + " 参数配置非法; ");
                        continue;
                    }

                    mHandle[index] = NETClient.RealPlay(m_lUserID,  item.ChannelNo, item.Handle);
                    if (IntPtr.Zero == mHandle[index])
                    {
                        msgBuider.Append("大华设备通道号" + item.ChannelNo + " 预览失败，错误编码:" + NETClient.GetLastError()).Append("; ");
                    }
                }

                rs = ResultEntity.Success(msgBuider.ToString());
            }
            catch (Exception ex)
            {
                rs = ResultEntity.Error("大华设备通道预览异常:" + ex.Message + ex.StackTrace);
            }

            return rs;
        }


        /// <summary>
        /// 停止预览
        /// </summary>
        /// <returns></returns>
        public ResultEntity StopPlay()
        {
            var rs = ResultEntity.Default();
            try
            {
                bool b = true;
                StringBuilder ContentBuider = new StringBuilder();
                for (int index = 0; index < mHandle.Count; index++)
                {
                    if (mHandle[index] !=IntPtr.Zero)
                    {
                        bool ret = NETClient.StopRealPlay(mHandle[index]);
                        if (!ret)
                        {
                            b = false;
                            ContentBuider.Append("大华通道停止预览出错, error code= " + NETClient.GetLastError()).Append(";");
                        }
                        mHandle[index] = IntPtr.Zero;
                    }
                }

                if (b)
                {
                    rs = ResultEntity.Success("大华通道停止预览成功");
                }
                else
                {
                    rs = ResultEntity.Error(ContentBuider.ToString());
                }
            }
            catch (Exception ex)
            {
                rs = ResultEntity.Error("大华停止通道预览异常:" + ex.Message + ex.StackTrace);
            }
            return rs;
        }



        /// <summary>
        /// 抓拍图片
        /// </summary>
        /// <param name="path"></param>
        public ResultEntity CaptureImg(CaptureParamEntity entity)
        {
            Thread task = new Thread(new ParameterizedThreadStart(CaptureImgTask)) { IsBackground = true };
            task.Start(entity);
            return ResultEntity.Success("大华调用抓拍图片功能成功!");
        }


        /// <summary>
        /// 抓拍图片任务
        /// </summary>
        private void CaptureImgTask(object obj)
        {
            CaptureParamEntity entity = obj as CaptureParamEntity;
            if (entity == null) return;
            StringBuilder MsgBuider = new StringBuilder();
            Dictionary<string, bool> ImgIsExist = new Dictionary<string, bool>();
            for (int i = 0; i < mHandle.Count; i++)
            {
                try
                {
                    IntPtr handler = mHandle[i];
                    if (entity.Path.Length == 0) return;

                    string fileName = entity.Path + "\\" + entity.Prefix + "_" + i.ToString() + ".jpg";
                    if (fileName.Contains("\\\\")) fileName.Replace("\\\\", "\\");
                    if (fileName.Contains("//")) fileName.Replace("//", "/");
                    if (File.Exists(fileName)) File.Delete(fileName);

                    if (!NETClient.CapturePicture(handler, fileName, EM_NET_CAPTURE_FORMATS.JPEG))
                    {
                        MsgBuider.Append("大华抓拍BMP图片出错, error code= " + NETClient.GetLastError()).Append("; 路径:")
                            .Append(fileName);
                    }
                    else
                    {
                        ImgIsExist.Add(fileName, false);
                    }

                }
                catch (Exception ex)
                {
                    MsgBuider.Append("大华抓拍图片异常:" + ex.Message + ex.StackTrace);
                    continue;
                }
            }


            List<string> successList = new List<string>();
            List<string> Keys = new List<string>(ImgIsExist.Keys);
            ImageHandler imgHander = new ImageHandler();
            try
            {
                int index = 0;
                while (index < 10)
                {
                    for (int i = 0; i < Keys.Count; i++)
                    {
                        if (File.Exists(Keys[i]))
                        {
                            if (!ImgIsExist[Keys[i]])
                            {
                                if (entity.Ratio != 100)
                                {
                                    ResultEntity result = imgHander.CompressImg(Keys[i], entity.Ratio);
                                    if (result.State != 1)
                                    {
                                        MsgBuider.Append(result.Message);
                                    }
                                }

                                if (entity.DrawingParam != null)
                                {
                                    entity.DrawingParam.Path = Keys[i];
                                    ResultEntity result = imgHander.DrawString(entity.DrawingParam);
                                    if (result.State != 1)
                                    {
                                        MsgBuider.Append(result.Message);
                                    }
                                }
                                successList.Add(Keys[i]);
                                ImgIsExist[Keys[i]] = true;
                            }
                        }
                        else
                        {
                            Thread.Sleep(300);
                        }
                    }

                    foreach (bool item in ImgIsExist.Values)
                    {
                        if (!item)
                        {
                            Thread.Sleep(200);
                            break;
                        }
                    }
                    index++;
                }

            }
            catch (Exception ex)
            {
                MsgBuider.Append("大华处理图片异常:" + ex.Message + ex.StackTrace);
            }

            if (entity.CallBack != null)
            {
                entity.CallBack(entity.Id, MsgBuider.ToString(), successList);
            }
        }

        /// <summary>
        /// 关闭设备
        /// </summary>
        /// <returns></returns>
        public ResultEntity Close()
        {
            var rs = ResultEntity.Default();
            try
            {
                var stopRs = StopPlay();
                var logOutRs = logOut();
                rs = ResultEntity.Success("大华停止预览:" + stopRs.Message + "; 注销登录" + logOutRs.Message);
            }
            catch (Exception ex)
            {
                rs = ResultEntity.Error("大华硬盘录像机关闭异常:" + ex.Message + ex.StackTrace);
            }
            return rs;
        }


        #region CallBack  大华回调
        private void DisConnectCallBack(IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser)
        {
        }

        private void UpdateDisConnectUI()
        {
        }

        private void ReConnectCallBack(IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser)
        {
        }
        private void UpdateReConnectUI()
        {
        }

        private void RealDataCallBackEx(IntPtr lRealHandle, uint dwDataType, IntPtr pBuffer, uint dwBufSize, IntPtr param, IntPtr dwUser)
        {
            //do something such as save data,send data,change to YUV. 比如保存数据，发送数据，转成YUV等.
        }

        private void SnapRevCallBack(IntPtr lLoginID, IntPtr pBuf, uint RevLen, uint EncodeType, uint CmdSerial, IntPtr dwUser)
        {
            //string path = AppDomain.CurrentDomain.BaseDirectory + "capture";
            //if (!Directory.Exists(path))
            //{
            //    Directory.CreateDirectory(path);
            //}
            //if (EncodeType == 10) //.jpg
            //{
            //    DateTime now = DateTime.Now;
            //    string fileName = "async" + CmdSerial.ToString() + ".jpg";
            //    string filePath = path + "\\" + fileName;
            //    byte[] data = new byte[RevLen];
            //    Marshal.Copy(pBuf, data, 0, (int)RevLen);
            //    using (FileStream stream = new FileStream(filePath, FileMode.OpenOrCreate))
            //    {
            //        stream.Write(data, 0, (int)RevLen);
            //        stream.Flush();
            //        stream.Dispose();
            //    }
            //}
        }
        #endregion

    }
}


